package org.mspring.mlog.service.impl;

import net.sf.ehcache.Element;

import org.mspring.mlog.entity.NewsExt;
import org.mspring.mlog.service.NewsExtService;
import org.mspring.platform.cache.service.CacheService;
import org.mspring.platform.cache.service.DefaultCacheService;
import org.mspring.platform.persistence.hibernate.BaseHibernateDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 
 * @author Gao Youbo
 * @since 2013年7月9日
 */
@Service
@Transactional
public class NewsExtServiceImpl extends BaseHibernateDao<NewsExt, Long> implements NewsExtService {
    /**
     * 获取新闻点击率时，多久从数据库中获取一次
     */
    public static final Long NEWS_VIEWS_CACHE_TIME = CacheService.ONE_MINUTE * 10;

    /**
     * 当新闻点击量累积到多少时进行一次数据持久化
     */
    public static final Integer UPDATE_VIEWS_BATCH = 10;

    /**
     * 临时缓存新闻点击率的cachekey前缀
     */
    public static final String NEWS_VIEWS_UPDATE_CACHE = "NEWS_VIEWS_UPDATE_CACHE_";

    @Autowired
    private DefaultCacheService defaultCacheService;

    @Override
    public void updateCachedViews(Long newsId) {
        // TODO Auto-generated method stub
        Long views = Long.valueOf(1);
        Element ele = defaultCacheService.getCache().get(NEWS_VIEWS_UPDATE_CACHE + newsId);
        if (ele != null && ele.getValue() != null) {
            views = Long.valueOf(ele.getValue().toString()) + 1;
        }

        long one_hour = CacheService.ONE_HOUR * 1000; // 一小时的毫秒数
        // 如果该新闻缓存中保存的点击率大于UPDATE_VIEWS_BATCH，或者缓存时间超过一个小时，那么将缓存数据更新到数据库一次
        if (views >= UPDATE_VIEWS_BATCH || (ele != null && System.currentTimeMillis() - ele.getCreationTime() > one_hour)) {
            executeUpdate("update NewsExt ext set ext.views = ext.views + ? where ext.newsId = ?", views, newsId);
            defaultCacheService.deleteDefaultCacheValue(NEWS_VIEWS_UPDATE_CACHE + newsId);
        } else {
            defaultCacheService.updateDefaultCacheValue(NEWS_VIEWS_UPDATE_CACHE + newsId, views, CacheService.ONE_DAY);
        }
    }

    @Override
    public Long getCachedViews(Long newsId) {
        // TODO Auto-generated method stub
        try {
            Object obj = defaultCacheService.getDefaultCacheValue(getNewsViewsCacheKey(newsId));
            if (obj != null) {
                return Long.valueOf(obj.toString());
            }
            Object viewsObj = uniqueResult("select ext.views from NewsExt ext where ext.newsId = ?", newsId);
            if (viewsObj != null) {
                Long views = (Long) viewsObj;
                defaultCacheService.updateDefaultCacheValue(getNewsViewsCacheKey(newsId), views, NEWS_VIEWS_CACHE_TIME);
                return views;
            }
            return Long.valueOf(0);
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
            return Long.valueOf(0);
        }
    }

    /**
     * 获取新闻点击量的缓存KEY
     * 
     * @param newsId
     * @return
     */
    private String getNewsViewsCacheKey(Long newsId) {
        return "NEWS_VIEWS_" + newsId;
    }

}
